/*
 * ConnectionManager.java
 *
 * Created on 16 luglio 2005, 0.52
 * 
 * The core engine of BtFree
 *
 *@version 1.1
 *@author Federico Paparoni
 *
 */

package com.javastaff.btfree;
import java.util.*;
import javax.microedition.io.*;
import javax.bluetooth.*;
import java.io.*;

public class ConnectionManager {
    private StreamConnection conn;
    private OutputStream os;
    private InputStream is;
    private Receiver r;
    private ReceivingThread receivingThread;
    
    /**
     * @param conn StreamConnection that will be used to manage the Input and Output streams
     */
    
    public ConnectionManager(StreamConnection conn) {
        this.conn=conn;
    }
    
    /**
     * @return true if streams have been created
     */
    
    public boolean createStreams() {
        try {
            os  = conn.openOutputStream();
            is  = conn.openInputStream();
            return true;
        }
        catch(Exception e) {
            return false;
        }
    
    }
    
    /**
     * @return InputStream created
     */
    
    public InputStream getInputStream() {
        return is;
    }
    
    /**
     * @return OutputStream created
     */
    
    public OutputStream getOutputStream() {
        return os;
    }
    
    /**
     * @param msg A message that will be sent by ConnectionManager
     * @return true if the message was sent
     */
    
    public boolean sendMSG(Message msg) {
        try {
            int len=msg.getLength();
            byte lengthPayload[]=Utilities.intToArray(len);
            os.write(lengthPayload);
            os.flush();
            os.write(msg.getMessage());
            os.flush();
            return true;
        }
        catch(Exception e) {
            return false;
        }
    }
    
    /**
     * @param r Receiver that will receive the message from ConnectionManager
     */
    
    public void setReceiver(Receiver r) {
        this.r=r;
        receivingThread=new ReceivingThread(r,is);
        receivingThread.start();
    }
}

class ReceivingThread extends Thread {
    private Receiver r;
    private InputStream is;
    private boolean running=true;
    private int len;
    
    /**
     * @param r Receiver that will receive the message
     * @param is InputStream the thread is reading
     */
    public ReceivingThread(Receiver r,InputStream is) {
        this.r=r;
        this.is=is;
    }
    
    public void run() {
        try {
            while(running) {
                len=readLength();
                if (len==0)
                    r.connectionClosed();
                
                byte[] msgArray=readMsg();
                BlueMessage msg=new BlueMessage(new String(msgArray));
                r.messageArrived(msg);
            }
        }
        catch(Exception e){
        }
    }
    
    
    /**
     * @return byte array representing the message content
     */
    
    public byte[] readMsg() {
        try {
            byte[] msgArray=new byte[len];
            is.read(msgArray);
            return msgArray;
        }
        catch(Exception e) {
            return null;
        }
    }
    
    /**
     * @return length of the receiving message
     */
    
    public int readLength() {
        try {
            byte[] lengthArray=new byte[4];
            is.read(lengthArray);
            int len=Utilities.arrayToInt(lengthArray);
            return len;
        }
        catch(Exception e) {
            return 0;
        }
    }
}
